package hu.myai.model.sp;

import hu.myai.model.db.AxHistory;
import hu.myai.model.graph.DirectionNode;
import hu.myai.model.graph.ElliotNode;
import hu.myai.model.graph.FibNode;
import hu.myai.util.Constans;
import hu.myai.util.Util;

import java.util.Date;

import org.joone.log.ILogger;
import org.joone.log.LoggerFactory;

public abstract class StockPivot {

	private static final ILogger log = LoggerFactory.getLogger(StockPivot.class);

	private Util util = new Util();

	/**
	 * this is the value of local top or button
	 */
	protected double value;

	/**
	 * this is the date of a value of local top or button
	 */
	protected Date location;

	/**
	 * This represents the wave position of the current stock pivot
	 */
	private ElliotNode elliotNode;

	/**
	 * This represents the fibonacci level of the current stock pivot
	 */
	private FibNode fibNode;

	/**
	 * This represents the fibonacci fan level from max of the current stock
	 * pivot
	 */
	private FibNode fibMaxFanNode;

	/**
	 * This represents the fibonacci fan level from min of the current stock
	 * pivot
	 */
	private FibNode fibMinFanNode;

	/**
	 * This represents the position of the current stock pivot
	 */
	private DirectionNode directionNode = (DirectionNode) Constans.bf_direction.getBean("direction_init");

	/**
	 * This is an attribute of the high of the stock pivot
	 */
	protected int direction;

	/**
	 * This contains a distance from the main support in %
	 */
	private double percentFromSupport;

	/**
	 * This contains a distance from the season max fan support in %
	 */
	private double percentFromFanMaxSupport;

	/**
	 * This contains a distance from the season min fan support in %
	 */
	private double percentFromFanMinSupport;

	/**
	 * This contains a percent of the season max fibonacci fan line support. It
	 * is for fibonacci fan calculation
	 */
	private double tangensAlphafromMax;

	/**
	 * This contains a percent of the season min fibonacci fan line support. It
	 * is for fibonacci fan calculation
	 */
	private double tangensAlphafromMin;

	public double getPercentFromSupport() {
		return percentFromSupport;
	}

	public void setPercentFromSupport(double percentFromSupport) {
		this.percentFromSupport = percentFromSupport;
	}

	protected StockPivot(Date location, double value, DirectionNode direction) {
		this.location = location;
		this.value = value;
		this.directionNode = direction;
	}

	protected void setStockPivot(Date location, double value, DirectionNode direction) {
		this.value = value;
		this.location = location;
		this.directionNode = direction;
	}

	abstract protected void setStockPivot(AxHistory history);

	public double getValue() {
		return logFilter(value);
	}

	public double getOrigValue() {
		return value;
	}

	public Date getLocation() {
		return location;
	}

	public ElliotNode getElliotNode() {
		return elliotNode;
	}

	public void setElliotNode(ElliotNode elliotNode) {
		this.elliotNode = elliotNode;
	}

	public FibNode getFibNode() {
		return fibNode;
	}

	public void setFibNode(FibNode fibNode) {
		this.fibNode = fibNode;
	}

	public DirectionNode getDirectionNode() {
		return directionNode;
	}

	public void setDirectionNode(DirectionNode directionNode) {
		this.directionNode = directionNode;
	}

	public int getDirection() {
		return direction;
	}

	/**
	 * transform the value logaritmic
	 * 
	 * @param value
	 *            for convert it
	 * @return ln(value)
	 */
	private double logFilter(double value) {

		if (Constans.logarithmic == true) {
			// most values are between 0.001 and 100. That cause trouble at
			// log().
			if (value <= 0) {
				return 0;
			} else {
				return Math.log(value * 1000);
			}
		} else
			return value;
	}

	public static double valueNormalizer(double value) {

		if (Constans.logarithmic == true) {
			// most values are between 0.001 and 100. That cause trouble at
			// log().
			if (value < 1)
				return 0;
			else {
				return Math.exp(value) / 1000;
			}
		} else
			return value;
	}

	@Override
	public String toString() {
		return location.toString() + "  " + util.trim(value) + "\t "
				+ (directionNode != null ? directionNode.getName() : "null ") + ",\t "
				+ (fibNode != null ? fibNode.getName() : "    null") + ",\t "
				+ (fibMaxFanNode != null ? fibMaxFanNode.getName() : "    null") + ",\t "
				+ (fibMinFanNode != null ? fibMinFanNode.getName() : "    null") + ",\t "
				+ (elliotNode != null ? elliotNode.getName() : "null") + ",\t " + util.trim(percentFromSupport)
				+ "%,\t" + util.trim(percentFromFanMaxSupport) + "%,\t" + util.trim(percentFromFanMinSupport) + "%";
	}

	public FibNode getFibMaxFanNode() {
		return fibMaxFanNode;
	}

	public void setFibMaxFanNode(FibNode fibMaxFanNode) {
		this.fibMaxFanNode = fibMaxFanNode;
	}

	public FibNode getFibMinFanNode() {
		return fibMinFanNode;
	}

	public void setFibMinFanNode(FibNode fibMinFanNode) {
		this.fibMinFanNode = fibMinFanNode;
	}

	public double getPercentFromFanMaxSupport() {
		return percentFromFanMaxSupport;
	}

	public void setPercentFromFanMaxSupport(double percentFromFanMaxSupport) {
		this.percentFromFanMaxSupport = percentFromFanMaxSupport;
	}

	public double getPercentFromFanMinSupport() {
		return percentFromFanMinSupport;
	}

	public void setPercentFromFanMinSupport(double percentFromFanMinSupport) {
		this.percentFromFanMinSupport = percentFromFanMinSupport;
	}

	public double getTangensAlphafromMax() {
		return tangensAlphafromMax;
	}

	public void setTangensAlphafromMax(double tangensAlphafromMax) {
		this.tangensAlphafromMax = tangensAlphafromMax;
	}

	public double getTangensAlphafromMin() {
		return tangensAlphafromMin;
	}

	public void setTangensAlphafromMin(double tangensAlphafromMin) {
		this.tangensAlphafromMin = tangensAlphafromMin;
	}

}
